<?php
/**
 * 定时任务逻辑层
 * @author 王勇程 <laughskydragon@qq.com>
 */

namespace app\common\logic;

class Task extends LogicBase
{
    /**
     * 处理过期VIP用户
     */
    public function processExpiredVip()
    {
        try {
            \think\facade\Log::info('开始处理过期VIP用户');
            
            // 调用User模型的处理过期VIP方法
            $processedCount = $this->modelUser->processExpiredVip();
            
            // 记录日志
            if ($processedCount > 0) {
                \think\facade\Log::info("处理过期VIP用户完成，共处理{$processedCount}个用户");
                action_log('定时任务', "处理过期VIP用户，共处理{$processedCount}个用户");
            } else {
                \think\facade\Log::info('没有需要处理的过期VIP用户');
            }
            
            return [RESULT_SUCCESS, "处理完成，共处理{$processedCount}个过期VIP用户", ['processed_count' => $processedCount]];
            
        } catch (\Exception $e) {
            \think\facade\Log::error('处理过期VIP用户失败：' . $e->getMessage());
            return [RESULT_ERROR, '处理过期VIP用户失败：' . $e->getMessage()];
        }
    }
    
    /**
     * 发送VIP过期提醒
     */
    public function sendVipExpireReminder()
    {
        try {
            \think\facade\Log::info('开始发送VIP过期提醒');
            
            $totalSent = 0;
            
            // 发送3天过期提醒
            $users3Days = $this->modelUser->getVipUsersNearExpire(3);
            foreach ($users3Days as $user) {
                $this->modelUser->sendVipExpireMessage($user['id'], 3);
                $totalSent++;
            }
            
            // 发送1天过期提醒
            $users1Day = $this->modelUser->getVipUsersNearExpire(1);
            foreach ($users1Day as $user) {
                $this->modelUser->sendVipExpireMessage($user['id'], 1);
                $totalSent++;
            }
            
            // 记录日志
            if ($totalSent > 0) {
                \think\facade\Log::info("VIP过期提醒发送完成，共发送{$totalSent}条消息");
                action_log('定时任务', "发送VIP过期提醒，共发送{$totalSent}条消息");
            } else {
                \think\facade\Log::info('没有需要发送VIP过期提醒的用户');
            }
            
            return [RESULT_SUCCESS, "提醒发送完成，共发送{$totalSent}条消息", [
                'sent_count' => $totalSent,
                'users_3_days' => count($users3Days),
                'users_1_day' => count($users1Day)
            ]];
            
        } catch (\Exception $e) {
            \think\facade\Log::error('发送VIP过期提醒失败：' . $e->getMessage());
            return [RESULT_ERROR, '发送VIP过期提醒失败：' . $e->getMessage()];
        }
    }
    
    /**
     * 清理过期数据
     */
    public function cleanupExpiredData()
    {
        try {
            \think\facade\Log::info('开始清理过期数据');
            
            $cleanupCount = 0;
            
            // 清理30天前的已读消息
            $expiredMessages = $this->modelMessage->getList([
                'is_read' => 1,
                'create_time' => ['<', strtotime('-30 days')]
            ], 'id', '', false);
            
            foreach ($expiredMessages as $message) {
                $this->modelMessage->deleteInfo(['id' => $message['id']]);
                $cleanupCount++;
            }
            
            // 清理90天前的取消订单
            if (property_exists($this, 'modelVipOrder')) {
                $canceledOrders = $this->modelVipOrder->getList([
                    'status' => 2, // 已取消
                    'create_time' => ['<', strtotime('-90 days')]
                ], 'id', '', false);
                
                foreach ($canceledOrders as $order) {
                    $this->modelVipOrder->deleteInfo(['id' => $order['id']]);
                    $cleanupCount++;
                }
            }
            
            // 记录日志
            if ($cleanupCount > 0) {
                \think\facade\Log::info("过期数据清理完成，共清理{$cleanupCount}条记录");
                action_log('定时任务', "清理过期数据，共清理{$cleanupCount}条记录");
            } else {
                \think\facade\Log::info('没有需要清理的过期数据');
            }
            
            return [RESULT_SUCCESS, "清理完成，共清理{$cleanupCount}条记录", ['cleanup_count' => $cleanupCount]];
            
        } catch (\Exception $e) {
            \think\facade\Log::error('清理过期数据失败：' . $e->getMessage());
            return [RESULT_ERROR, '清理过期数据失败：' . $e->getMessage()];
        }
    }
    
    /**
     * 获取任务执行状态
     */
    public function getTaskStatus()
    {
        try {
            // 获取VIP用户统计
            $vipStats = [
                'total_vip_users' => $this->modelUser->stat(['vip_level' => ['>', 0]], 'count'),
                'expired_vip_users' => $this->modelUser->stat([
                    'vip_level' => ['>', 0],
                    'vip_expire_time' => ['<=', time()]
                ], 'count'),
                'expiring_3_days' => count($this->modelUser->getVipUsersNearExpire(3)),
                'expiring_1_day' => count($this->modelUser->getVipUsersNearExpire(1))
            ];
            
            // 获取消息统计
            $messageStats = [
                'total_messages' => $this->modelMessage->stat([], 'count'),
                'unread_messages' => $this->modelMessage->stat(['is_read' => 0], 'count'),
                'old_read_messages' => $this->modelMessage->stat([
                    'is_read' => 1,
                    'create_time' => ['<', strtotime('-30 days')]
                ], 'count')
            ];
            
            $status = [
                'vip_stats' => $vipStats,
                'message_stats' => $messageStats,
                'last_check_time' => date('Y-m-d H:i:s'),
                'server_time' => date('Y-m-d H:i:s')
            ];
            
            return [RESULT_SUCCESS, '任务状态获取成功', $status];
            
        } catch (\Exception $e) {
            \think\facade\Log::error('获取任务状态失败：' . $e->getMessage());
            return [RESULT_ERROR, '获取任务状态失败：' . $e->getMessage()];
        }
    }
    
    /**
     * 检查系统健康状态
     */
    public function checkSystemHealth()
    {
        try {
            $health = [
                'database' => $this->checkDatabaseHealth(),
                'storage' => $this->checkStorageHealth(),
                'memory' => $this->checkMemoryUsage(),
                'timestamp' => time()
            ];
            
            return [RESULT_SUCCESS, '系统健康检查完成', $health];
            
        } catch (\Exception $e) {
            \think\facade\Log::error('系统健康检查失败：' . $e->getMessage());
            return [RESULT_ERROR, '系统健康检查失败：' . $e->getMessage()];
        }
    }
    
    /**
     * 检查数据库健康状态
     */
    private function checkDatabaseHealth()
    {
        try {
            // 简单的数据库连接测试
            $result = \think\facade\Db::query('SELECT 1');
            return ['status' => 'ok', 'message' => '数据库连接正常'];
        } catch (\Exception $e) {
            return ['status' => 'error', 'message' => '数据库连接异常：' . $e->getMessage()];
        }
    }
    
    /**
     * 检查存储健康状态
     */
    private function checkStorageHealth()
    {
        try {
            $uploadPath = app()->getRootPath() . 'public/uploads';
            if (!is_dir($uploadPath)) {
                return ['status' => 'warning', 'message' => '上传目录不存在'];
            }
            
            if (!is_writable($uploadPath)) {
                return ['status' => 'error', 'message' => '上传目录不可写'];
            }
            
            $freeSpace = disk_free_space($uploadPath);
            $totalSpace = disk_total_space($uploadPath);
            $usagePercent = round(($totalSpace - $freeSpace) / $totalSpace * 100, 2);
            
            return [
                'status' => $usagePercent > 90 ? 'warning' : 'ok',
                'message' => "磁盘使用率：{$usagePercent}%",
                'free_space' => $freeSpace,
                'total_space' => $totalSpace
            ];
        } catch (\Exception $e) {
            return ['status' => 'error', 'message' => '存储检查异常：' . $e->getMessage()];
        }
    }
    
    /**
     * 检查内存使用情况
     */
    private function checkMemoryUsage()
    {
        try {
            $memoryUsage = memory_get_usage(true);
            $memoryPeak = memory_get_peak_usage(true);
            $memoryLimit = ini_get('memory_limit');
            
            return [
                'status' => 'ok',
                'current_usage' => $memoryUsage,
                'peak_usage' => $memoryPeak,
                'memory_limit' => $memoryLimit,
                'usage_mb' => round($memoryUsage / 1024 / 1024, 2),
                'peak_mb' => round($memoryPeak / 1024 / 1024, 2)
            ];
        } catch (\Exception $e) {
            return ['status' => 'error', 'message' => '内存检查异常：' . $e->getMessage()];
        }
    }
}